@namespace Oqtane.Modules.Controls
@inherits ModuleControlBase
@inject IStringLocalizer<RichTextEditor> Localizer 

<div class="row" style="margin-bottom: 50px;">
    <div class="col">
        <TabStrip>
            <TabPanel Name="Rich" Heading="Rich Text Editor" ResourceKey="RichTextEditor">
				@if (_richfilemanager)
				{
					<FileManager @ref="_fileManager" Filter="@Constants.ImageFiles" />
					<ModuleMessage Message="@_message" Type="MessageType.Warning"></ModuleMessage>
					<br />
				}
				<div class="d-flex justify-content-center mb-2">
					@if (AllowRawHtml)
					{
						<button type="button" class="btn btn-secondary" @onclick="RefreshRichText">@Localizer["SynchronizeContent"]</button>@((MarkupString)"&nbsp;&nbsp;")
					}
					@if (AllowFileManagement)
					{
						<button type="button" class="btn btn-primary" @onclick="InsertRichImage">@Localizer["InsertImage"]</button>
					}
					@if (_richfilemanager)
					{
						@((MarkupString)"&nbsp;&nbsp;")
						<button type="button" class="btn btn-secondary" @onclick="CloseRichFileManager">@Localizer["Close"]</button>
					}
				</div>
				<div class="row">
					<div class="col">
						<div @ref="@_toolBar">
							@if (ToolbarContent != null)
							{
								@ToolbarContent
							}
							else
							{
								<select class="ql-header">
									<option selected=""></option>
									<option value="1"></option>
									<option value="2"></option>
									<option value="3"></option>
									<option value="4"></option>
									<option value="5"></option>
								</select>
								<span class="ql-formats">
									<button class="ql-bold"></button>
									<button class="ql-italic"></button>
									<button class="ql-underline"></button>
									<button class="ql-strike"></button>
								</span>
								<span class="ql-formats">
									<select class="ql-color"></select>
									<select class="ql-background"></select>
								</span>
								<span class="ql-formats">
									<button class="ql-list" value="ordered"></button>
									<button class="ql-list" value="bullet"></button>
								</span>
								<span class="ql-formats">
									<button class="ql-link"></button>
								</span>
							}
						</div>
						<div @ref="@_editorElement">
						</div>
					</div>
				</div>
			</TabPanel>
			@if (AllowRawHtml)
			{
				<TabPanel Name="Raw" Heading="Raw HTML Editor" ResourceKey="HtmlEditor">
					@if (_rawfilemanager)
					{
						<FileManager @ref="_fileManager" Filter="@Constants.ImageFiles" />
						<ModuleMessage Message="@_message" Type="MessageType.Warning"></ModuleMessage>
						<br />
					}
					<div class="d-flex justify-content-center mb-2">
						<button type="button" class="btn btn-secondary" @onclick="RefreshRawHtml">@Localizer["SynchronizeContent"]</button>&nbsp;&nbsp;
						@if (AllowFileManagement)
						{
							<button type="button" class="btn btn-primary" @onclick="InsertRawImage">@Localizer["InsertImage"]</button>
						}
						@if (_rawfilemanager)
						{
							@((MarkupString)"&nbsp;&nbsp;")
							<button type="button" class="btn btn-secondary" @onclick="CloseRawFileManager">@Localizer["Close"]</button>
						}
					</div>
					@if (ReadOnly)
					{
						<textarea id="rawhtmleditor" class="form-control" placeholder="@Placeholder" @bind="@_rawhtml" rows="10" readonly></textarea>
					}
					else
					{
						<textarea id="rawhtmleditor" class="form-control" placeholder="@Placeholder" @bind="@_rawhtml" rows="10"></textarea>
					}
				</TabPanel>
			}
        </TabStrip>
    </div>
</div>

@code {
	private ElementReference _editorElement;
	private ElementReference _toolBar;
	private bool _richfilemanager = false;
	private FileManager _fileManager;
	private string _richhtml = string.Empty;
	private string _originalrichhtml = string.Empty;
	private bool _rawfilemanager = false;
	private string _rawhtml = string.Empty;
	private string _originalrawhtml = string.Empty;
	private string _message = string.Empty;

	[Parameter]
	public string Content { get; set; }

	[Parameter]
	public bool ReadOnly { get; set; } = false;

	[Parameter]
	public string Placeholder { get; set; } = "Enter Your Content...";

	[Parameter]
	public bool AllowFileManagement { get; set; } = true;

	[Parameter]
	public bool AllowRawHtml { get; set; } = true;  
	
	// parameters only applicable to rich text editor
	[Parameter]
	public RenderFragment ToolbarContent { get; set; }

	[Parameter]
	public string Theme { get; set; } = "snow";

	[Parameter]
	public string DebugLevel { get; set; } = "info";

	public override List<Resource> Resources => new List<Resource>()
    {
        new Resource { ResourceType = ResourceType.Script, Bundle = "Quill", Url = "js/quill.min.js" },
        new Resource { ResourceType = ResourceType.Script, Bundle = "Quill", Url = "js/quill-blot-formatter.min.js" },
        new Resource { ResourceType = ResourceType.Script, Bundle = "Quill", Url = "js/quill-interop.js" }
    };

	protected override void OnParametersSet()
	{
		_richhtml = Content;
		_rawhtml = Content;
		_originalrawhtml = _rawhtml; // preserve for comparison later
	}

	protected override async Task OnAfterRenderAsync(bool firstRender)
	{
		await base.OnAfterRenderAsync(firstRender);

		var interop = new RichTextEditorInterop(JSRuntime);

		if (firstRender)
		{
			await interop.CreateEditor(
				_editorElement,
				_toolBar,
				ReadOnly,
				Placeholder,
				Theme,
				DebugLevel);

			await interop.LoadEditorContent(_editorElement, _richhtml);

			// preserve a copy of the rich text content (Quill sanitizes content so we need to retrieve it from the editor)
			_originalrichhtml = await interop.GetHtml(_editorElement);
		}
	}

	public void CloseRichFileManager()
	{
		_richfilemanager = false;
		_message = string.Empty;
		StateHasChanged();
	}

	public void CloseRawFileManager()
	{
		_rawfilemanager = false;
		_message = string.Empty;
		StateHasChanged();
	}

	public void RefreshRichText()
	{
		_richhtml = _rawhtml;
		StateHasChanged();
	}

	public async Task RefreshRawHtml()
	{
		var interop = new RichTextEditorInterop(JSRuntime);
		_rawhtml = await interop.GetHtml(_editorElement);
		StateHasChanged();
	}

	public async Task<string> GetHtml()
	{
		// evaluate raw html content as first priority
		if (_rawhtml != _originalrawhtml)
		{
			return _rawhtml;
		}
		else
		{
			// return rich text content if it has changed
			var interop = new RichTextEditorInterop(JSRuntime);
			var richhtml = await interop.GetHtml(_editorElement);
			if (richhtml != _originalrichhtml)
			{
				return richhtml;
			}
			else
			{
				// return original raw html content
				return _originalrawhtml;
			}
		}
	}

	public async Task InsertRichImage()
	{
		_message = string.Empty;
		if (_richfilemanager)
		{
			var file = _fileManager.GetFile();
			if (file != null)
			{
				var interop = new RichTextEditorInterop(JSRuntime);
				await interop.InsertImage(_editorElement, file.Url, ((!string.IsNullOrEmpty(file.Description)) ? file.Description : file.Name));
				_richfilemanager = false;
			}
			else
			{
				_message = Localizer["Message.Require.Image"];
			}
		}
		else
		{
			_richfilemanager = true;
		}
		StateHasChanged();
	}

	public async Task InsertRawImage()
	{
		_message = string.Empty;
		if (_rawfilemanager)
		{
			var file = _fileManager.GetFile();
			if (file != null)
			{
				var interop = new Interop(JSRuntime);
				int pos = await interop.GetCaretPosition("rawhtmleditor");
				var image = "<img src=\"" + file.Url + "\" alt=\"" + ((!string.IsNullOrEmpty(file.Description)) ? file.Description : file.Name) + "\" class=\"img-fluid\">";
				_rawhtml = _rawhtml.Substring(0, pos) + image + _rawhtml.Substring(pos);
				_rawfilemanager = false;
			}
			else
			{
				_message = Localizer["Message.Require.Image"];
			}
		}
		else
		{
			_rawfilemanager = true;
		}
		StateHasChanged();
	}
}
